#include "SGConfig.h"

#include <fstream>
#include <iostream>

#include "boost/algorithm/string.hpp"
#include "boost/filesystem.hpp"
#include "nlohmann/json.hpp"

#include "Utility/Logging/SGLogger.h"

#ifdef _WIN32
#include <windows.h>
#else
#include <limits.h>
#include <unistd.h>
#endif

using namespace SG::Utility;

SGConfig::SGConfig (const std::string& config)
{
    if (!LoadConfig (config))
    {
        SGWarn << "Can't find config file: " << config << '\n';
    }
}

SGConfig& SGConfig::GetInstance ()
{
    static SGConfig config (CONFIG_FILE_NAME);
    return config;
}

bool SGConfig::LoadConfig (const std::string& config)
{
    boost::filesystem::path result;

#ifdef _WIN32
    char buffer[MAX_PATH];
    GetModuleFileName (NULL, buffer, MAX_PATH);
    result = boost::filesystem::path (buffer).parent_path ();
#else
    char    buffer[PATH_MAX];
    ssize_t len = ::readlink ("/proc/self/exe", buffer, sizeof (buffer) - 1);
    if (len != -1)
    {
        buffer[len] = '\0';
        result      = boost::filesystem::path (buffer).parent_path ();
    }

#endif

    auto configpath = result / config;
    SGTrace << "Config Path:" << configpath;
    // 判断文件是否存在
    if (!boost::filesystem::exists (configpath))
    {
        return false;
    }

    try
    {
        std::ifstream  f (configpath);
        nlohmann::json data = nlohmann::json::parse (f);

        m_data = SGParameter (data.dump ());
    }
    catch (const std::exception& e)
    {
        SGError << e.what () << '\n';
        return false;
    }

    return true;
}

SGParameter& SGConfig::GetData ()
{
    return m_data;
}
